package com.jrx.anytxn.customer.handel.impl;

import com.jrx.anytxn.common.data.TxnRespCode;
import com.jrx.anytxn.common.exception.TxnBizException;
import com.jrx.anytxn.common.uitl.BeanMapping;
import com.jrx.anytxn.customer.constant.BankCardConstant;
import com.jrx.anytxn.customer.constant.CustomerConstant;
import com.jrx.anytxn.customer.constant.ErrorMsgConstant;
import com.jrx.anytxn.customer.dto.BaseApiReq;
import com.jrx.anytxn.customer.dto.BaseApiRes;
import com.jrx.anytxn.customer.dto.bankcardinfo.*;
import com.jrx.anytxn.customer.entity.CmCustomerBankcardInfo;
import com.jrx.anytxn.customer.entity.CmCustomerSecondLevel;
import com.jrx.anytxn.customer.handel.IBankCardInfoHandler;
import com.jrx.anytxn.customer.service.IBankCardService;
import com.jrx.anytxn.customer.service.ICustomerService;
import com.jrx.anytxn.redisson.service.RedissonLockService;
import com.jrx.anytxn.redisson.util.LockType;
import org.redisson.api.RLock;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

/**
 * 银行卡handler
 *
 * @author Yangxin
 * @date 2019-08-09 14:08
 **/
@Component
public class BankCardInfoHandlerImpl implements IBankCardInfoHandler {
    private static Logger logger = LoggerFactory.getLogger(BankCardInfoHandlerImpl.class);

    @Autowired
    private IBankCardService bankCardService;

    @Autowired
    private ICustomerService customerService;
    @Autowired
    private RedissonLockService redissonLockService;


    @Override
    public BankCardBindRes registerBankCardBind(BankCardBindReq bankCardBindReq) throws Exception {

        //a)根据渠道id、用户user_id判断渠道在客户二级信息表中是否已存在该客户记录；
        //b)根据客户id，判断用户在客户一级信息表中是否已存在客户记录；
        CmCustomerSecondLevel customersInfo = customerService.getSecondLevelByCondition(bankCardBindReq.getUserId(),
                bankCardBindReq.getChannel(), bankCardBindReq.getTenantId(), null);
        //绑定银行加锁
        String lockKey = String.format(CustomerConstant.LOCK_BANK, customersInfo.getTenantId(), customersInfo.getUserId(), customersInfo.getChannel());
        logger.info("RedissionLock key:{}",lockKey);
        RLock lock = redissonLockService.getRLock(lockKey, LockType.REENTRANT_LOCK);
        try {
            boolean lockFlag = lock.tryLock(CustomerConstant.REDIS_LOCK_WAITE_TIME, CustomerConstant.REDIS_LOCK_LESS_TIME, TimeUnit.SECONDS);
            logger.info("获取RedissionLock key:{},lockFlag:{}",lockKey,lockFlag);
            if (!lockFlag) {
                throw new TxnBizException(TxnRespCode.CARD_IS_BANDING_ERROR.getCode(), TxnRespCode.CARD_IS_BANDING_ERROR.getMsg());
            }

            //根据卡号+客户ID查询此客户的银行卡信息
            CmCustomerBankcardInfo cmCustomerBankcardInfo = bankCardService.getBankByChannleAndCusIdAndCardNum(null,
                    bankCardBindReq.getChannel(), bankCardBindReq.getCardNumber(), bankCardBindReq.getTenantId());

            //判断银行卡是否已存在，判断银行卡绑定客户id与当前绑定卡的客户id是否一致
            if (cmCustomerBankcardInfo != null && !cmCustomerBankcardInfo.getCustomerId().equalsIgnoreCase(customersInfo.getCustomerId())) {
                logger.error(ErrorMsgConstant.BANKCARD_DATA);
                throw new TxnBizException(TxnRespCode.DATA_EXISTS.getCode(), TxnRespCode.DATA_EXISTS.getUserTips());
            }
            //若银行卡信息存在且卡状态为绑定，抛异常；为解绑状态则将此卡的解绑状态改为绑定状态，即绑定
            if (cmCustomerBankcardInfo != null && cmCustomerBankcardInfo.getCardStatus().equals(BankCardConstant.STATUS_BANKCARD_1)) {
                logger.error(ErrorMsgConstant.BANKCARD_DATA);
                throw new TxnBizException(TxnRespCode.CARD_BAND_ERROR.getCode(), TxnRespCode.CARD_BAND_ERROR.getUserTips());
            }
            //绑定新卡
            return bankCardService.saveBankCard(bankCardBindReq, customersInfo, cmCustomerBankcardInfo);
        } finally {
            lock.unlock();
        }
    }


    @Override
    public BaseApiRes modifyBankCardUnBind(BankCardUnBindReq bankCardUnBindReq) throws TxnBizException {

        //a)根据渠道id、用户user_id判断渠道在客户二级信息表中是否已存在该客户记录；
        //b)根据客户id，判断用户在客户一级信息表中是否已存在客户记录；
        CmCustomerSecondLevel customersInfo = customerService.getSecondLevelByCondition(bankCardUnBindReq.getUserId(),
                bankCardUnBindReq.getChannel(), bankCardUnBindReq.getTenantId(), null);

        //对该卡片做解除绑定处理：更新该卡片信息并保存客户银行卡信息表

        return bankCardService.modifyBankCardInfo(bankCardUnBindReq, customersInfo.getCustomerId(), customersInfo.getUserId());
    }

    @Override
    public BankCardListRes getBankCardList(BaseApiReq bankCardListReq) throws TxnBizException {
        BankCardListRes res = BeanMapping.copy(bankCardListReq, BankCardListRes.class);

        //根据渠道id、用户user_id判断渠道在客户二级信息表中是否已存在该客户记录；
        CmCustomerSecondLevel customersInfo = customerService.getSecondLevelByCondition(bankCardListReq.getUserId(), bankCardListReq.getChannel(), bankCardListReq.getTenantId(), null);
        //获取客户id
        String customerId = customersInfo.getCustomerId();
        //根据客户id+渠道查询客户银行卡信息表，获得客户当前所有绑定状态的银行卡列表

        res.setBindCardList(bankCardService.getBankCardList(customerId, bankCardListReq.getChannel(), BankCardConstant.STATUS_BANKCARD_1, bankCardListReq.getTenantId()));

        return res;
    }

    @Override
    public BaseApiRes modifyFlagBankCard(BankCardSetFlagReq bankCardSetFlagReq) throws Exception {

        //a)根据渠道id、用户user_id判断渠道在客户二级信息表中是否已存在该客户记录；
        //b)根据客户id，判断用户在客户一级信息表中是否已存在客户记录；
        String lockKey = String.format(CustomerConstant.LOCK_BANK, bankCardSetFlagReq.getTenantId(), bankCardSetFlagReq.getUserId(), bankCardSetFlagReq.getChannel());
        logger.info("RedissionLock key:{}",lockKey);
        RLock lock = redissonLockService.getRLock(lockKey, LockType.REENTRANT_LOCK);
        try {
            boolean lockFlag = lock.tryLock(CustomerConstant.REDIS_LOCK_WAITE_TIME, CustomerConstant.REDIS_LOCK_LESS_TIME, TimeUnit.SECONDS);
            logger.info("获取RedissionLock key:{},lockFlag:{}",lockKey,lockFlag);
            if (!lockFlag) {
                throw new TxnBizException(TxnRespCode.CARD_IS_BANDING_ERROR.getCode(), TxnRespCode.CARD_IS_BANDING_ERROR.getMsg());
            }
            CmCustomerSecondLevel customersInfo = customerService.getSecondLevelByCondition(bankCardSetFlagReq.getUserId(),
                    bankCardSetFlagReq.getChannel(), bankCardSetFlagReq.getTenantId(), null);

            //对该卡片做设置默认收还款标志处理：更新该卡片信息并保存客户银行卡信息表

            return bankCardService.modifyBankCardSetFlag(bankCardSetFlagReq, customersInfo.getCustomerId());
        } finally {
            lock.unlock();
        }
    }
}
